namespace EyeSoft.Wpf.Facilities
{
	using System;
	using System.Collections.Generic;
	using System.Linq;

	using EyeSoft.Mapping;
	using EyeSoft.Wpf.Facilities.Collections.ObjectModel;

	internal class DataService<TService>
		where TService : IDisposable
	{
		private readonly IMapper mapper;

		private readonly IDisposableFactory<TService> proxyFactory;

		public DataService(
			IMapper mapper,
			IDisposableFactory<TService> proxyFactory)
		{
			this.mapper = mapper;
			this.proxyFactory = proxyFactory;
		}

		public void LoadEnumerable<T, TCollectionType>(
			Func<TService, IEnumerable<T>> func,
			SmartObservableCollection<TCollectionType> collection)
		{
			using (var service = proxyFactory.Create())
			{
				var data = func(service);

				var dataConverted =
					typeof(T) != typeof(TCollectionType) ?
						data.Select(item => mapper.Map<TCollectionType>(item)) :
						data.Select(item => (TCollectionType)(object)item);

				collection.AddRange(dataConverted);
			}
		}

		public T LoadItem<T>(Func<TService, T> func)
		{
			using (var service = proxyFactory.Create())
			{
				var data = func(service);

				return data;
			}
		}

		public void Execute<T>(T arg, Action<TService, T> action)
		{
			using (var service = proxyFactory.Create())
			{
				action(service, arg);
			}
		}
	}
}